package fetcher

import (
	"bufio"
	"fmt"
	"golang.org/x/net/html/charset"
	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/unicode"
	"golang.org/x/text/transform"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

var rateLimiter = time.Tick(100 * time.Millisecond)

func Fetch(url string) ([]byte, error) {
	<-rateLimiter
	request, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		return nil, err
	}

	request.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36")
	request.Header.Add("refer", "https://www.zhenai.com/")
	cookie1 := `sid=b1c8d047-0d5e-4a52-9125-a5c65da764fa; ec=Ks9DDGCo-1612666117775-ce891e5516af51415274143; FSSBBIl1UgzbN7NO=59u8Hsa9F7OwGm.Ic1vB69_W0NoQn.B8CmEYlCqNxrrIbkQc1Zht81A.2QkrEMLzmExDBP57iUB56opufgCcxcA; spliterabparams=1612666237926:-650141699964750953; Hm_lvt_2c8ad67df9e787ad29dbd54ee608f5d2=1615386038,1615469813,1615471437,1616423438; Hm_lpvt_2c8ad67df9e787ad29dbd54ee608f5d2=1616424070; _efmdata=sppoilnWyHBMgJydJPDtV+VxLdDMGmcgcRuhXc7P9aqpnQ9DP0fRj3QHSOr9pakGzKelInL1enOo+zSsllGtEbaZ/oolsVZlozMw9+wP8kk=; _exid=cFOjzVymE1OZmBU1CZKYWMFZViQk+5SBBQ18tXSHzt++TEfHvjwy5FN+l3Y/6hkCHRWv+IpPPnTHT2Jz2+HZxA==; FSSBBIl1UgzbN7NP=53mPj6Dr3jjlqqqmgKbW1RqEj2cFrplGc3iXtpajQsrR1FnJqMVio0._odQwvGZev4H0hjfZ3W47neCcLNBIxguA_vqmuqnKhwa4RKhsko2cNb0oW8fqGEjcSEYTUlkuvF9BcjzRMgHSyVAUPJPnquheXBy6yjyz1t6MnjHC9P0ghIXU6atdaws96J6mew07wq9rBIA9rCdh2qo58203kLmHac3DA6bWwxyL_mhMRziH54xt2j6DWE9H00PKjyuComlQu1O0lHRbV1DjuK3aBhCkMnDMRg.jRh4u6KMCboAAV_guy9d5bJuGqAJN.7zdKL`
	request.Header.Add("cookie", cookie1)

	client := http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("wrong status code: %d", resp.StatusCode)
	}

	bodyReader := bufio.NewReader(resp.Body)
	e := determineEncoding(bodyReader)
	utf8Reader := transform.NewReader(bodyReader, e.NewDecoder())
	return ioutil.ReadAll(utf8Reader)
}

func determineEncoding(r *bufio.Reader) encoding.Encoding {
	bytes, err := r.Peek(1024)
	if err != nil {
		log.Printf("Fetcher Error: %v", err)
		return unicode.UTF8
	}

	e, _, _ := charset.DetermineEncoding(bytes, "")
	return e
}
